# 自己实现一个具有加, 减, 乘, 除, 整除, 取余, 乘方, 开方的计算器
from math import sqrt
import re


# 加
def add(x, y):
    return x + y


# 减
def sub(x, y):
    return x - y


# 乘
def mul(x, y):
    return x * y


# 除（Float Division）
def float_div(x, y):
    try:
        return x / y
    except ZeroDivisionError:
        print('不能用 0 做除数！！！')


# 地板除（Floor Division）
def floor_div(x, y):
    try:
        return x // y
    except ZeroDivisionError:
        print('不能用 0 做除数！！！')


# 取余（Modulus）
def mod(x, y):
    return x % y


# 乘方（Power）
def power(x, y):
    return x ** y


# 开方（Square root），平方根
def my_sqrt(x):
    return sqrt(x)


def calculate(operate, original_numbers):
    func_dict = {'+': add, '-': sub, '*': mul, '/': float_div, '//': floor_div, '%': mod, '**': power, 'sqrt': my_sqrt}
    # 平方根较为特殊，只有一个参数，单独处理
    if operate == 'sqrt':
        try:
            num = original_numbers.lstrip('sqrt').strip()
            result = func_dict[operate](float(num))
            return result
        except ValueError:
            # float参数不合法和sqrt()传负数都会报ValueError
            print('输入不合法，开平方操作只能针对正数哦！！！')
            return
    if operate in func_dict:
        # 减法由于可能是负数的减法（如-3-8），避免将第一个"-"认成减法运算，需要单独处理
        if operate == '-' and original_numbers.startswith('-'):
            numbers = original_numbers.replace(' ', '').lstrip('-').split(operate, 1)
            numbers[0] = '-' + numbers[0]
        else:
            numbers = original_numbers.replace(' ', '').split(operate, 1)
        try:
            result = func_dict[operate](float(numbers[0]), float(numbers[1]))
            return result
        except ValueError:
            how_to_use()
            print('！！！！！无法计算，请参考如上格式重新输入！！！！！')


def how_to_use():
    print('简易计算器'.center(60, '='))
    print('简易计算器，可实现，加减乘除、地板除（//）、求余数（%）、乘方、开平方')
    print('加 操作请使用 +，如 1+2')
    print('减 操作请使用 -，如 1-2')
    print('乘 操作请使用 *，如 1*2')
    print('除 操作请使用 /，如 1/2')
    print('地板除（向下取整） 操作请使用 //，如 1//2')
    print('求余数 操作请使用 %，如 1%2')
    print('求乘方 操作请使用 **，如 1**2')
    print('求开平方 操作请使用 sqrt，如 sqrt 4')
    print('输入q，按回车键退出程序')
    print('=' * 61)


if __name__ == '__main__':
    # print(add(1, 2), sub(1, 2), mul(1, 2), float_div(1, 2),
    #      floor_div(1, 2), mod(1, 2), power(1, 2), my_sqrt(4))
    how_to_use()
    while True:
        user_input = input('请输入算式（例如 1+2）：').strip()
        if user_input == 'q':
            exit()

        if user_input.startswith('sqrt'):
            res = calculate('sqrt', user_input)
            if res is not None:
                print(user_input, '=', res)
            continue

        if '+' in user_input:
            res = calculate('+', user_input)
            if res is not None:
                print(user_input, '=', res)
            continue

        if '**' in user_input:
            res = calculate('**', user_input)
            if res is not None:
                print(user_input, '=', res)
            continue

        if '*' in user_input:
            res = calculate('*', user_input)
            if res is not None:
                print(user_input, '=', res)
            continue

        if '//' in user_input:
            res = calculate('//', user_input)
            if res is not None:
                print(user_input, '=', res)
            continue

        if '/' in user_input:
            res = calculate('/', user_input)
            if res is not None:
                print(user_input, '=', res)
            continue

        if '%' in user_input:
            res = calculate('%', user_input)
            if res is not None:
                print(user_input, '=', res)
            continue

        # 减法符号还有负数意思，避免歧义，放在最后判断。
        if '-' in user_input:
            res = calculate('-', user_input)
            if res is not None:
                print(user_input, '=', res)
            continue
        how_to_use()
        print('！！！！！无法计算，请参考如上格式重新输入！！！！！')
